﻿using AdminManager.Permissions;
using AdminManager.System.OrganizationUnits;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;

namespace AdminManager.System
{
    [Authorize(AdminManagerPermissions.OrganizationUnits.Default)]
    public class OrganizationUnitsAppService : ApplicationService, IOrganizationUnitsAppService
    {
        private readonly IRepository<OrganizationUnit> _organizaitonUnitRepository;
        
        private readonly OrganizationUnitManager _organizationUnitManager; 
        
        public OrganizationUnitsAppService(OrganizationUnitManager organizationUnitManager,
            IRepository<OrganizationUnit> organizaitonUnitRepository)
        {
            this._organizationUnitManager = organizationUnitManager;
            this._organizaitonUnitRepository = organizaitonUnitRepository; 
        }
        [Authorize(AdminManagerPermissions.OrganizationUnits.Create)]
        public async Task<OrganizationUnitDto> CreateAsync(OrganizationUnitDto organizationUnitDto)
        {
            OrganizationUnit item = new OrganizationUnit(GuidGenerator.Create(), organizationUnitDto.DisplayName
                , organizationUnitDto.ParentId);
            await this._organizationUnitManager.CreateAsync(item);
            return organizationUnitDto;
        }

        public async Task<List<OrganizationUnitDto>> GetAllListAsync()
        {
            List<OrganizationUnit> list = await this._organizaitonUnitRepository.GetListAsync();
            return ObjectMapper.Map<List<OrganizationUnit>,List<OrganizationUnitDto>>(list);
        }

        public async Task<OrganizationUnitDto> GetAsync(string id)
        {
            var item = await (await this._organizaitonUnitRepository.GetQueryableAsync()).AsNoTracking().FirstOrDefaultAsync(p => p.Id == Guid.Parse(id));
            if (item == null)
            {
                throw new BusinessException(AdminManagerDomainErrorCodes.NotFoundData);
            }
            return ObjectMapper.Map<OrganizationUnit, OrganizationUnitDto>(item);
        }

        public async Task<List<OrganizationUnitDto>> GetListAsync(OrganizationUnitSearchDto searchDto)
        {
            var itemlist = await (await this._organizaitonUnitRepository.GetQueryableAsync()).AsNoTracking().ToListAsync();
            if (!string.IsNullOrWhiteSpace(searchDto.DisplayName))
            {
                itemlist = itemlist.Where(p=>p.DisplayName.Contains(searchDto.DisplayName)).ToList();
            } 
            return ObjectMapper.Map<List<OrganizationUnit>, List<OrganizationUnitDto>>(itemlist);
        }
        [Authorize(AdminManagerPermissions.OrganizationUnits.Update)]
        public async Task<OrganizationUnitDto> UpdateAsync(string id, OrganizationUnitDto organizationUnitDto)
        {
            var item = await _organizaitonUnitRepository.FirstOrDefaultAsync(p => p.Id == Guid.Parse(id));
            if (item == null)
            {
                throw new BusinessException(AdminManagerDomainErrorCodes.NotFoundData);
            }
            //update 
            if (item.DisplayName != organizationUnitDto.DisplayName)
            {
                item.DisplayName = organizationUnitDto.DisplayName;
                await this._organizationUnitManager.UpdateAsync(item);
            }
            //move
            if (item.ParentId != organizationUnitDto.ParentId)
            {
                await this._organizationUnitManager.MoveAsync(item.Id, organizationUnitDto.ParentId);
            }
            return organizationUnitDto;
        } 
     
    }
}